package leetcode.top100;

import java.util.LinkedList;
import java.util.List;

/**
 * 给定一个整数数组 a，其中1 ≤ a[i] ≤ n （n为数组长度）,
 *
 * 其中有些元素出现两次而其他元素出现一次。
 *
 * 找到所有出现两次的元素。
 *
 * 你可以不用到任何额外空间并在O(n)时间复杂度内解决这个问题吗？
 *
 * 示例：
 *
 * 输入:
 * [4,3,2,7,8,2,3,1]
 *
 * 输出:
 * [2,3]
 *
 * 其他相关见{@link leetcode.a_总结分布.Code02_数组中缺失或重复数字}
 * @date 2020/4/15 14:18
 */
public class Code442_FindAllRepeatNum {
    //方式1：使用set统计，略。
    //方式2：排序，略。
    //方式3：使用标记法
    public List<Integer> findDuplicates(int[] nums) {
        List<Integer> res = new LinkedList<>();
        if(nums == null || nums.length <= 1) return res;
        //把1-n标记到 0-n-1索引上
        for (int i = 0; i < nums.length; i++) {
            int index = Math.abs(nums[i]) - 1;
            //已经出现过了，
            if(nums[index] < 0) {
                res.add(index+1);
            }else {
                nums[index] = -nums[index];
            }
        }
        //还原略
        return res;
    }
}
